/*
 * @Author: 橘子
 * @Date: 2022-09-30 21:54:25
 * @Project_description: 项目介绍
 * @Description: 代码是我抄的，不会也是真的
 */
import util from '@/libs/util'
import cookies from '@/libs/util.cookies'
import router from '@/router/index'
import setting from '@/setting'
import axios from 'axios'
import { Message } from 'element-ui'
import { get } from 'lodash'
import { errorCreate } from './tools'
//配置
const axiosConfig = setting.axiosConfig
// 是否允许重复提交
const isSubmit = axiosConfig.isSubmit

/**
 * @description 创建请求实例
 */
function createService() {
  // 创建一个 axios 实例
  const service = axios.create()
  // 请求拦截
  service.interceptors.request.use(
    (config) => {
      if (isSubmit) {
        //如果有就是在请求
        let ck = cookies.get(config.url)
        if (ck) {
          Message.error('正在发起请求，请稍等')
          return
        }
        // 处理当前路由
        if (!config.repeat) {
          cookies.setRouter(config.url, true)
        }
        // cookies.setRouter(config.url, true)
      }

      return config
    },
    (error) => {
      return Promise.reject(error)
    },
  )
  // 响应拦截
  service.interceptors.response.use(
    (response) => {
      //获取更新的token
      const { newtoken } = response.headers
      //如果token存在则刷新
      if (newtoken) {
        util.cookies.set('token', newtoken)
        console.log('新的token', util.cookies.get('token'))
      }
      if (isSubmit) {
        //拿到请求就把当前这个删除了
        if (!response.config.repeat) {
          cookies.remove(response.config.url)
        }
      }
      // dataAxios 是 axios 返回数据中的 data
      const dataAxios = response.data
      // 这个状态码是和后端约定的
      const { code } = dataAxios
      // 根据 code 进行判断
      if (undefined === code) {
        // 如果没有 code  代表可能是下载文件等操作
        return dataAxios
      } else if (401 === code) {
        // 清除token
        util.cookies.remove('token')
        // 跳转路由
        router.push({
          path: '/login',
        })
        errorCreate(dataAxios.msg || 'token失效')
      } else {
        // 有 code 代表这是一个后端接口 可以进行进一步的判断
        if (axiosConfig.successCode == code) {
          return dataAxios
        }
        // 其他都是未知或者错误
        const msg = axiosConfig.errorCode[code] || dataAxios.msg || aixosCofing.errorCode['default']
        errorCreate(msg)
      }
    },
    (error) => {
      const status = get(error, 'response.status')
      const err = get(error, 'response')
      if (!err) {
        //有可能是别的奇怪的请求，所以这里不处理
        error.message = '请检查api配置,或后端未启动'
      } else {
        if (isSubmit) {
          //拿到请求就把当前这个删除了
          if (!err.config.repeat) {
            cookies.remove(err.config.url)
          }
        }
        //判断参数是否为数组
        error.message = axiosConfig.errorCode[status] || err.data.msg || aixosCofing.errorCode['default']
      }
      errorCreate(error)
      return Promise.reject(error)
    },
  )
  return service
}

/**
 * @description 创建请求方法
 * @param {Object} service axios 实例
 */
function createRequestFunction(service) {
  return function(config) {
    let configDefault = {
      headers: {
        'Content-Type': get(config, 'headers.Content-Type', 'application/json'),
      },
      timeout: axiosConfig.timeout,
      baseURL: setting.appInfo.baseUrl,
      data: {},
    }
    //预留调试接口
    const url = util.cookies.get('baseUrl')
    if (url) {
      configDefault.baseURL = url
    }
    // 获取token
    const token = util.cookies.get('token')
    if (token && !config.noToken) {
      configDefault.headers['token'] = token
      // configDefault.headers.Authorization = 'Bearer ' + token
    }
    return service(Object.assign(configDefault, config))
  }
}

// 用于真实网络请求的实例和请求方法
export const service = createService()
export const request = createRequestFunction(service)
